package orchestration.android.execution.tasks;

import java.util.List;

import orchestration.android.RunExecutionActivity;
import orchestration.businessprocess.execution.Property;
import orchestration.utils.PropertyUtils;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;

/**
 * @author  <a href="mailto:car.ferrarini@gmail.com">Carlo Ferrarini</a>
 */
public class ServiceOperation {
	
	/**
	 * @uml.property  name="inputId"
	 */
	private List<String> inputId;
	/**
	 * @uml.property  name="outputId"
	 */
	private String outputId;
	/**
	 * @uml.property  name="opCode"
	 */
	private int opCode;
	
	/**
	 * @return
	 * @uml.property  name="outputId"
	 */
	public String getOutputId() {
		return outputId;
	}
	/**
	 * @param outputId
	 * @uml.property  name="outputId"
	 */
	public void setOutputId(String outputId) {
		this.outputId = outputId;
	}
	/**
	 * @param inputId
	 * @uml.property  name="inputId"
	 */
	public void setInputId(List<String> inputId) {
		this.inputId = inputId;
	}
	/**
	 * @return
	 * @uml.property  name="inputId"
	 */
	public List<String> getInputId() {
		return inputId;
	}
	
	/**
	 * @return
	 * @uml.property  name="opCode"
	 */
	public int getOpCode() {
		return opCode;
	}
	/**
	 * @param opCode
	 * @uml.property  name="opCode"
	 */
	public void setOpCode(int opCode) {
		this.opCode = opCode;
	}
	public void exec(AidlFile aidl, IBinder binder, RunExecutionActivity rea) throws RemoteException {
		List<Property> input=rea.getProperties(getInputId());
		Property output=null;
		String outputName = getOutputId();
		if(outputName!=null)
			output=rea.getProperty(outputName);
		
		
		Parcel data= Parcel.obtain();
		data.writeInterfaceToken(aidl.getDescriptor());
		fillParcel(data,input);
		Parcel reply= Parcel.obtain();
		try{
			binder.transact(IBinder.FIRST_CALL_TRANSACTION+opCode, data, reply, 0);
			reply.readException();
			if(output!=null){
				PropertyUtils.readPropertyValueFromParcel(reply, output);
				rea.saveProperty(output);
			}
		}
		finally {
			reply.recycle();
			data.recycle();
		}
	}
	private void fillParcel(Parcel data, List<Property> props) {
		for(Property prop : props){
			PropertyUtils.writePropertyValueToParcel(data, prop);
		}
	}
	
	
}
